package meatslope2.gameengine.engine;

import android.util.Log;
import meatslope2.application.Game;
import meatslope2.gameengine.engine.Engine.Time;
import meatslope2.gameengine.gameobjects.Player;
import meatslope2.gameengine.helpers.Utils;
import meatslope2.gameengine.primatives.Vector2;

public class Camera 
{
	// ===========================================================
	// Constants
	// ===========================================================
	
	//States
	private static final int INITIAL_CHASE = 0;
	private static final int CHASE = 1;
	private static final int SLOW_CHASE = 2;
	private static final int STOP = 3;
	
	//Distances
	private static final float SNAP_DISTANCE = 30f;
	private static final float SLOW_DISTANCE = 100f;
	private static final float CHASE_DISTANCE = 125f;
	
	//Speeds
	private static final float SLOW_ACCELERATION = 75f;
	private static final float SPEED = 100f;
	
	private static final float MINIMUM_SPEED = 10f;

	// ===========================================================
	// Members
	// ===========================================================
	private final Vector2 position = new Vector2();
	private final Game game;
	private final Player player;
	
	private float currentSpeed = 0;
	private float currentAcceleration = 0;
	private int direction = 0;
	
	private int currentState = STOP;
	
	// ===========================================================
	// Getters/Setters
	// ===========================================================
	
	public final Vector2 getPosition()
	{
		return this.position;
	}
	
	private final float getAbsoluteDistanceFromPlayer()
	{
		return Math.abs(getDistanceFromPlayer());
	}
	
	private final float getDistanceFromPlayer()
	{
		 return getCenter() - player.getPosition().x;
	}
	
	private float getCenter()
	{
		return position.x + (game.getWidth() / 2);
	}
	
	// ===========================================================
	// Constructors
	// ===========================================================
	
	public Camera(Game game, Player player)
	{
		assert game != null : "incoming game cannot equal null";
		assert player != null : "incoming player cannot equal null";
		
		this.game = game;
		this.player = player;
	}
	
	// ===========================================================
	// Methods
	// ===========================================================
	
	public void update()
	{
		switch(currentState)
		{
			case INITIAL_CHASE:
			{
				this.direction = getCenter() < player.getPosition().x ? 1 : -1;
				
				this.currentSpeed = SPEED * direction;
				this.currentAcceleration = SLOW_ACCELERATION * direction;
				
				this.currentState = CHASE;
				break;
			}
			case CHASE:
			{
				this.position.x += this.currentSpeed * Time.getDeltaTime();
				
				if(getAbsoluteDistanceFromPlayer() < SLOW_DISTANCE)
					this.currentState = SLOW_CHASE;
			}
				break;
			case SLOW_CHASE:
				final float tempSpeed = currentSpeed - this.currentAcceleration * Time.getDeltaTime(); //Need to check this value before assigning
				
				//This fixes the problem of the camera slowing down so much before it reaches the player that it changes direction
				if(direction == 1 && tempSpeed < MINIMUM_SPEED)
					this.currentSpeed = MINIMUM_SPEED;
				else if(direction == -1 && tempSpeed > -MINIMUM_SPEED)
					this.currentSpeed = -MINIMUM_SPEED;
				else
					this.currentSpeed = tempSpeed;

				this.position.x += this.currentSpeed * Time.getDeltaTime();
				
				if(getAbsoluteDistanceFromPlayer() < SNAP_DISTANCE)
					this.currentState = STOP;
				else if(getAbsoluteDistanceFromPlayer() > CHASE_DISTANCE)
					this.currentState = INITIAL_CHASE;
				break;
			case STOP:
			{
				if(getAbsoluteDistanceFromPlayer() > CHASE_DISTANCE)
					currentState = INITIAL_CHASE;
				break;				
			}
		}
		
		Log.e("state:", "" + currentState);
	}
}
